package com.hm.health;

import android.app.Activity;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.Build;
import android.os.IBinder;
import android.util.Log;

import androidx.multidex.MultiDex;

import com.goodix.CrashHandler.AppLifeCycleListener;
import com.goodix.CrashHandler.CrashHandler;
import com.goodix.comsdk.RomaDevice;
import com.goodix.comsdk.testsdk.IHBDTestClient;
import com.goodix.http.jsonparams.request.UploadCfgInfoParams;
import com.goodix.http.jsonparams.response.LoginResponse;
import com.goodix.ini.HbdOptionIni;
import com.goodix.keepalive.utils.KeepAliveManager;
import com.goodix.libromablecom.sdk.cardiff.CardiffEvkConfigUtils;
import com.goodix.libromablecom.sdk.cardiff.arguments.GetArgumentsKeyEnum;
import com.goodix.libromablecom.testsdk.BLEHBDTestClient;
import com.goodix.utils.RegexUtil;
import com.goodix.utils.SoundPoolUtil;
import com.hm.health.Activity.BaseActivity;
import com.hm.health.BLE.StandardHeartRateDevice;
import com.hm.health.entity.BleDevicesInfo;
import com.hm.health.entity.arguments.StartArgumentsManager;
import com.hm.health.notification.AppNotification;
import com.hm.health.provider.DataServiceManager;
import com.polidea.rxandroidble.RxBleClient;
import com.polidea.rxandroidble.internal.RxBleLog;

import org.litepal.LitePal;
import org.litepal.LitePalApplication;

import java.util.LinkedList;
import java.util.List;
import java.util.Locale;
import java.util.regex.Matcher;

public class MyApplication extends LitePalApplication {

    public static final boolean LOGIN_ENABLE = true;
    private static final String TAG = "MyApplication";
    private static MyApplication mSysApplication;
    private static RxBleClient mRxBleClient;
    private static StandardHeartRateDevice mStandardHeartRateDevice;
    private static IHBDTestClient mTestClient;
    private static HbdOptionIni sHbdOptionIni;

    private String          mSubjectName;
    private String          mSceneId;
    private String          mEarhang;
    private String          mRemarks;
    private static String   mStartMode = null;

    private List<Activity> mActivityList = new LinkedList<>();
    private LoginResponse mLoginResponse;
    private static String mUserName;
    private AppLifeCycleListener mAppLifeCycleListener;
    private boolean mIsPlayerRunning = false;
    private AppNotification mAppNotification = null;

    private static String[] mSceneChinese = {
            "默认",
            "静息",
            "上下楼梯",
            "室外慢跑",
            "跑步机",
            "休息",
            "动态跑步机",
            "高心率跑步",
            "跑步机组合跑",
            "室内自行车",
            "室外自行车",
            "室外自行车越野",
            "高强度运动组合",
            "传统力量训练组合",
            "台阶测试",
            "生活场景",
            "室外步行",
            "球类运动",
            "健身操",
            "憋气",
            "低温",
            "强光"
    };

    public static void setUserName(String userName) {
        mUserName = userName;
    }

    public static String getUserName() {
        return mUserName;
    }

    public StandardHeartRateDevice getStandardHeartRateDevice() {
        return mStandardHeartRateDevice;
    }

    public synchronized static MyApplication getInstance() {
        return mSysApplication;
    }

    public synchronized static RxBleClient getRxBleClient() {
        return mRxBleClient;
    }

    public static HbdOptionIni getHbdOptionIni() {
        return sHbdOptionIni;
    }

    public static void setHbdOptionIni(HbdOptionIni optionIni) {
        sHbdOptionIni = optionIni;
    }

    @Override
    public void onCreate() {
        super.onCreate();

        System.setProperty("rx.ring-buffer.size", String.valueOf(1024));

        mSysApplication = this;
        initStandardHeartRateService();
        RxBleClient.setLogLevel(RxBleLog.INFO);
        mRxBleClient = RxBleClient.create(this);
        updateCfgData();
        LitePal.initialize(this);
        mSubjectName = "ryan";
        mSceneId = getString(R.string.absolute_motionless);
        mEarhang = getString(R.string.no_ear_brace_info);
        CrashHandler.getInstance().init(this, BuildConfig.DEBUG);
        SoundPoolUtil.getInstance().init(getApplicationContext());
        mTestClient = BLEHBDTestClient.getInstance(getApplicationContext());
        mAppLifeCycleListener = new AppLifeCycleListener();
        registerActivityLifecycleCallbacks(mAppLifeCycleListener);
        KeepAliveManager.getInstance().showOnePixelActivity(this);
    }

    private void initStandardHeartRateService() {
        Intent intent = new Intent(this, StandardHeartRateDevice.class);
        boolean ok = bindService(intent, mStandardHeartRateConnection, Context.BIND_AUTO_CREATE);
        Log.d(TAG, "initStandardHeartRateService: bindService return -->" + ok);
    }

    private ServiceConnection mStandardHeartRateConnection = new ServiceConnection() {
        @Override
        public void onServiceConnected(ComponentName componentName, IBinder iBinder) {
            if (componentName.getClassName().equals(StandardHeartRateDevice.class.getName())) {
                StandardHeartRateDevice.ServiceBinder serviceBinder = (StandardHeartRateDevice.ServiceBinder)iBinder;
                Log.d(TAG, "onServiceConnected: StandardHeartRateDevice");
                if (null != serviceBinder) {
                    mStandardHeartRateDevice = serviceBinder.getService();
                }
            }
        }

        @Override
        public void onServiceDisconnected(ComponentName componentName) {
            if (componentName.getClassName().equals(StandardHeartRateDevice.class.getName())) {
                Log.e(TAG, "onServiceDisconnected: StandardHeartRateDevice");
                mStandardHeartRateDevice = null;
            }
        }
    };

    public boolean isAppOnForeground() {
        return mAppLifeCycleListener.isAppOnForeground();
    }

    @Override
    public void onTerminate() {

        if (null != mTestClient) {
            mTestClient.releaseClient();
        }

        if (null != mStandardHeartRateDevice) {
            mStandardHeartRateDevice.disconnect();
        }

        unbindService(mStandardHeartRateConnection);

        if (mIsPlayerRunning) {
            KeepAliveManager.getInstance().stopMediaPlayer();
        }

        if (mAppNotification != null) {
            mAppNotification.cancelNotification(AppNotification.NOTIFICATION_ID_1);
            mAppNotification = null;
        }

        super.onTerminate();
    }

    public void startMediaPlayer() {
//        if (sHbdOptionIni.isEnableKeepAliveFunction()) {
        mIsPlayerRunning = true;
        KeepAliveManager.getInstance().startMediaPlayer(getApplicationContext());
//        }
    }

    @Deprecated
    public void addActivity(Activity activity) {
//        mActivityList.add(activity);
    }

    public void addActivityEx(Activity activity) {
        mActivityList.add(activity);
        Log.d(TAG, "addActivityEx: " + activity.getClass().getName());
    }

    public void exit() {
        try {
            for (Activity activity : mActivityList) {
                if (activity != null) {
                    activity.finish();
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (null != getHBDTestClient()) {
                getHBDTestClient().releaseClient();
            }
            System.exit(0);
        }

    }

    public void updateCfgData() {
        //DataServiceManager.getInstance(getApplicationContext()).updateCfgData();
    }

    public String getSubjectName() {
        return mSubjectName;
    }

    public void setSubjectName(String subjectInfo) {
        Matcher matcher = RegexUtil.sFilePattern.matcher(subjectInfo);
        mSubjectName = matcher.replaceAll("-");
    }

    public String getEarhang(){
        return mEarhang;
    }

    public void setEarhang(String earhangInfo){
        mEarhang = earhangInfo;
    }

    public String getTesterInfo() {
        return String.format(Locale.ENGLISH,
                "%s-%s",
                StartArgumentsManager.getInstance().getSceneName(),
                MyApplication.getInstance().getSubjectName());
    }

    public static IHBDTestClient getHBDTestClient() {
        return mTestClient;
    }

    public UploadCfgInfoParams getUploadCfgParam(List<BleDevicesInfo> bleDevicesInfoList, long startTime) {
        UploadCfgInfoParams uploadCfgInfoParams = new UploadCfgInfoParams();
        uploadCfgInfoParams.setStartTime(startTime);
        uploadCfgInfoParams.setEndTime(System.currentTimeMillis());
        uploadCfgInfoParams.setTestId(System.currentTimeMillis() * 100 + (int) Math.random() % 100);
        uploadCfgInfoParams.setDataType(1);
        String sceneId = StartArgumentsManager.getInstance().getSceneName();
        String[] sceneArray = getResources().getStringArray(R.array.test_scene_array);
        for (int i = 0; i < sceneArray.length; i++) {
            if (sceneId.equals(sceneArray[i])) {
                sceneId = mSceneChinese[i];
                break;
            }
        }
        uploadCfgInfoParams.setSceneId(sceneId);
        uploadCfgInfoParams.setSceneIdInAlg(StartArgumentsManager.getInstance().getSceneId());
        uploadCfgInfoParams.setDriveConfig(CardiffEvkConfigUtils.getDriverConfigStr());
        uploadCfgInfoParams.setSubjectName(MyApplication.getInstance().getSubjectName());
        String earHang = MyApplication.getInstance().getEarhang();
        if (earHang.equals("no ear brace info")) {
            earHang = "无耳撑信息";
        }
        uploadCfgInfoParams.setEarHang(earHang);
        RomaDevice romaDevice = getHBDTestClient().getRomaDevice();

        String romaDeviceName = "roma";
        if ((null != romaDevice)
                && (romaDevice.getDeviceName() != null)
                && (!romaDevice.getDeviceName().isEmpty())) {
            romaDeviceName = romaDevice.getDeviceName();
        }

        int nCount = 0;
        if (null != bleDevicesInfoList) {
            for (BleDevicesInfo info : bleDevicesInfoList) {
                if (info.getDeviceAddress().equals(getHBDTestClient().getRomaDevice().getDeviceAddress())) {
                    continue;
                }
                if (0 == nCount) {
                    uploadCfgInfoParams.setDeviceOneName(info.getDeviceName());
                }

                if (1 == nCount) {
                    uploadCfgInfoParams.setDeviceTwoName(info.getDeviceName());
                }

                nCount++;
            }
        }

        uploadCfgInfoParams.setRomaName(romaDeviceName);
        uploadCfgInfoParams.setDeviceType(romaDevice.getDeviceType());
        uploadCfgInfoParams.setPhoneId(-1);
        uploadCfgInfoParams.setAppVersion(BuildConfig.VERSION_NAME);
        StringBuilder remarks = new StringBuilder();
        remarks.append(getHBDTestClient().getLibVersion());
        remarks.append("\n");
        remarks.append("mac-address:")
                .append(getHBDTestClient().getRomaDevice().getDeviceAddress())
                .append("\n");
        uploadCfgInfoParams.setRemarks(remarks.toString());
        uploadCfgInfoParams.setVendorName(Build.MANUFACTURER);
        uploadCfgInfoParams.setPhoneName(Build.PRODUCT);
        uploadCfgInfoParams.setOsVersion(Build.VERSION.RELEASE);
        uploadCfgInfoParams.setPhoneVersion(Build.MODEL);
        int sampleRate = Integer.decode(getHBDTestClient()
                .getRunTimeFlag(GetArgumentsKeyEnum.ARG_GET_SAMPLE_RATE));
        uploadCfgInfoParams.setFreq(sampleRate);
        uploadCfgInfoParams.setChipFreq(sampleRate);
        uploadCfgInfoParams.setMeasurementMode(StartArgumentsManager.getInstance().getFunctionName());

        return uploadCfgInfoParams;
    }

    @Override
    protected void attachBaseContext(Context base) {
        super.attachBaseContext(base);
        MultiDex.install(this);
    }

    public LoginResponse getLoginResponse() {
        return mLoginResponse;
    }

    public void setLoginResponse(LoginResponse response) {
        mLoginResponse = response;
    }

    public void removeActivity(BaseActivity activity) {
        mActivityList.remove(activity);
        activity.finish();
        Log.d(TAG, "removeActivity: " + activity.getClass().getName());
    }

}
